package com.yinshan.keyboard;

import android.content.Context;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.text.Editable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText;
import android.widget.PopupWindow;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;

/**
 * @author limh
 * @date: 2021/05/08 14:23
 * @@function: 自定义键盘
 */
public class YsKeyboardView extends KeyboardView {
    /**
     * 身份证键盘
     */
    public static final int KEYBOARDTYPE_ID_NUM = 0;
    /**
     * 数字键盘（密码）
     */
    public static final int KEYBOARDTYPE_NUM = 1;
    /**
     * 字母键盘
     */
    public static final int KEYBOARDTYPE_ABC = 2;
    /**
     * 符号键盘
     */
    public static final int KEYBOARDTYPE_SYMBOL = 4;

    private final String strLetter = "abcdefghijklmnopqrstuvwxyz";

    private EditText mEditText;
    private PopupWindow mWindow;

    private Keyboard keyboardIdNum;
    private Keyboard keyboardNum;
    private Keyboard keyboardAbc;
    private Keyboard keyboardSymbol;

    /**
     * 字母键盘 是否大写
     */
    public boolean isSupper = false;
    /**
     * 键盘是否随机 默认字母和数字随机 身份证键盘不判断
     */
    public boolean isRandom = true;

    public YsKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public YsKeyboardView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void init(EditText editText, PopupWindow window, int keyBoardType) {
        this.mEditText = editText;
        this.mWindow = window;
        setEnabled(true);
        setPreviewEnabled(false);
        setOnKeyboardActionListener(mOnKeyboardActionListener);
        setKeyBoardType(keyBoardType);
    }

    public EditText getEditText() {
        return mEditText;
    }

    /**
     * 设置键盘类型
     */
    public void setKeyBoardType(int keyBoardType) {
        switch (keyBoardType) {
            case KEYBOARDTYPE_ID_NUM:
                if (keyboardIdNum == null) {
                    keyboardIdNum = new Keyboard(getContext(), R.xml.keyboard_idnum);
                }
                setKeyboard(keyboardIdNum);
                break;
            case KEYBOARDTYPE_ABC:
                if (keyboardAbc == null) {
                    keyboardAbc = new Keyboard(getContext(), R.xml.keyboard_abc);
                }
                setKeyboard(keyboardAbc);
                break;
            case KEYBOARDTYPE_NUM:
                if (keyboardNum == null) {
                    keyboardNum = new Keyboard(getContext(), R.xml.keyboard_only_number);
                }
                if (isRandom) {
                    randomKeyNum(keyboardNum);
                }
                setKeyboard(keyboardNum);
                break;
            case KEYBOARDTYPE_SYMBOL:
                if (keyboardSymbol == null) {
                    keyboardSymbol = new Keyboard(getContext(), R.xml.keyboard_symbol);
                }
                setKeyboard(keyboardSymbol);
                break;
            default:
                break;
        }
    }


    private final OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {

        @Override
        public void onPress(int primaryCode) {

        }

        @Override
        public void onRelease(int primaryCode) {

        }

        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            Editable editable = mEditText.getText();
            int start = mEditText.getSelectionStart();
            switch (primaryCode) {
                case Keyboard.KEYCODE_DELETE://回退
                    if (editable != null && editable.length() > 0) {
                        if (start > 0) {
                            editable.delete(start - 1, start);
                        }
                    }
                    break;
                case Keyboard.KEYCODE_SHIFT://大小写切换
                    changeKey();
                    setKeyBoardType(KEYBOARDTYPE_ABC);
                    break;
                case Keyboard.KEYCODE_CANCEL:// 隐藏
                case Keyboard.KEYCODE_DONE:// 确认
                case 999999:
                    mWindow.dismiss();
                    break;
                case 456456://切换字母键盘
                    //如果当前为大写键盘，改为小写
                    if (isSupper) {
                        changeKey();
                    }
                    setKeyBoardType(KEYBOARDTYPE_ABC);
                    break;
                case 789789://切换符号键盘
                    setKeyBoardType(KEYBOARDTYPE_SYMBOL);
                    break;
                case 666666://人名分隔符·
                    editable.insert(start, "·");
                    break;
                case 111111:
                    break;
                default://字符输入
                    editable.insert(start, Character.toString((char) primaryCode));
            }
        }

        @Override
        public void onText(CharSequence text) {

        }

        @Override
        public void swipeLeft() {

        }

        @Override
        public void swipeRight() {

        }

        @Override
        public void swipeDown() {

        }

        @Override
        public void swipeUp() {

        }
    };

    /**
     * 键盘大小写切换
     */
    private void changeKey() {
        List<Keyboard.Key> keylist = keyboardAbc.getKeys();
        // 大写切小写
        if (isSupper) {
            for (Keyboard.Key key : keylist) {
                if (key.label != null && strLetter.contains(key.label.toString().toLowerCase())) {
                    key.label = key.label.toString().toLowerCase();
                    key.codes[0] = key.codes[0] + 32;
                }
            }
        } else {
            // 小写切大写
            for (Keyboard.Key key : keylist) {
                if (key.label != null && strLetter.contains(key.label.toString().toLowerCase())) {
                    key.label = key.label.toString().toUpperCase();
                    key.codes[0] = key.codes[0] - 32;
                }
            }
        }
        isSupper = !isSupper;
    }

    /**
     * 数字键盘随机
     * code 48-57 (0-9)
     */
    public void randomKeyNum(Keyboard pLatinKeyboard) {
        int[] ayRandomKey = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        SecureRandom random;
        try {
            random = SecureRandom.getInstance("SHA1PRNG");
            for (int i = 0; i < ayRandomKey.length; i++) {
                int a = random.nextInt(ayRandomKey.length);
                int temp = ayRandomKey[i];
                ayRandomKey[i] = ayRandomKey[a];
                ayRandomKey[a] = temp;
            }
            Log.d("key", Arrays.toString(ayRandomKey));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        List<Keyboard.Key> pKeyLis = pLatinKeyboard.getKeys();
        int index = 0;
        for (int i = 0; i < pKeyLis.size(); i++) {
            int code = pKeyLis.get(i).codes[0];
            if (code >= 48 && code <= 57) {
                pKeyLis.get(i).label = ayRandomKey[index] + "";
                pKeyLis.get(i).codes[0] = 48 + ayRandomKey[index];
                index++;
            }
        }
    }

    /**
     * 字母随机
     *
     * @param keyboardAbc 字母键盘随机
     */
    private void randomKeyAbc(Keyboard keyboardAbc) {
        int[] ayRandomKey = {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122};

        SecureRandom random;
        try {
            random = SecureRandom.getInstance("SHA1PRNG");
            for (int i = 0; i < ayRandomKey.length; i++) {
                int a = random.nextInt(ayRandomKey.length);
                int temp = ayRandomKey[i];
                ayRandomKey[i] = ayRandomKey[a];
                ayRandomKey[a] = temp;
            }
            Log.d("key", Arrays.toString(ayRandomKey));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        List<Keyboard.Key> pKeyLis = keyboardAbc.getKeys();
        int index = 0;
        for (int i = 0; i < pKeyLis.size(); i++) {
            int code = pKeyLis.get(i).codes[0];
            if ((code >= 'a' && code <= 'z') || (code >= 'A' && code <= 'Z')) {
                if (isSupper) {
                    pKeyLis.get(i).codes[0] = ayRandomKey[index] - 32;
                    pKeyLis.get(i).label = strLetter.toUpperCase().charAt(ayRandomKey[index] - 97) + "";
                } else {
                    pKeyLis.get(i).codes[0] = ayRandomKey[index];
                    pKeyLis.get(i).label = strLetter.charAt(ayRandomKey[index] - 97) + "";
                }
                index++;
            }
        }
    }
}
